/* =============================================================
 * common-method.js v1.1.0
 * =============================================================
 * Original written by Ysy
 * =============================================================
 * Date 04/06/2020
 * ============================================================ */

(function (factory) {
    "use strict";
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else {
        factory(jQuery);
    }
}(function ($) {

    let CommonMethod = function () {
    };

    CommonMethod.prototype = {

        constructor: CommonMethod,

        /*变量判断------------------------------------------------------------------------------start*/

        // 判断变量为字符串
        isString: function (str) {
            if (str && Object.is("string", typeof str)) return true;
            return false;
        },

        // 判断变量为数字
        isNumber: function (num) {
            if (num && Object.is("number", typeof num)) return true;
            return false;
        },

        // 判断变量为对象
        isObject: function (obj) {
            if (obj && obj instanceof Object) return true;
            return false;
        },

        // 判断变量为数组
        isArray: function (arr) {
            if (arr && arr instanceof Array) return true;
            return false;
        },
        /*变量判断------------------------------------------------------------------------------end*/

        /*字符串操作------------------------------------------------------------------------------start*/

        // 字符串非空判定
        isEmptyStr: function (str) {
            // 正则表达式用于判斷字符串是否全部由空格或换行符组成
            let reg = /^\s*$/;
            if (str && str !== undefined && str != null && str !== "" && !reg.test(str)) return false;

            return true;
        },

        // 字符串非空判定
        isNotEmptyStr: function (str) {
            return !this.isEmptyStr(str);
        },

        // 将  "{min=0,aver=0.10,max=0.60}"  转为对象
        strToObject: function (str) {
            let obj = {};
            if (!this.isString(str)) return obj;

            str = str.replace("{", "").replace("}", "");
            str.replace(/(\w+)(?:=([^,]*))?/g, (str, key, value) => {
                obj[key] = value;
            });

            return obj;
        },

        // 字符串转数字
        strToNumber: function (str, radix) {// radix:转换进制
            if (!this.isString(str)) return str;

            radix = radix ? radix : 10;// 如果是整数  默认10进制转换
            if (/^-?\d+$/.test(str)) {// 整数
                return Number.parseInt(str, radix);
            } else if (/^(-?\d+)(\.\d+)?$/.test(str)) {// 浮点数
                return Number.parseFloat(str);
            }

            return str;
        },

        // 对一个字符串或数字取整数或小数部分
        getNumberPart: function (param, type) {// type : int 代表取整数  float代表取小数
            let num = this.isString(param) ? this.strToNumber(param) : param;
            if (!this.isNumber(num)) return num;

            if (Object.is("int", type)) {// 取整数部分
                return Math.trunc(num);
            } else if (Object.is("float", type)) {// 取小数部分
                return this.subtraction(num, Math.trunc(num));
            }
            return param;
        },
        /*字符串操作------------------------------------------------------------------------------end*/

        /*数字操作------------------------------------------------------------------------------start*/

        // 将数字格式化为千分位
        numberFormatThousands: function (num) {
            if (!this.isNumber(num) && !this.isString(num)) return num;

            num = num.toString();

            let int = num.split(".")[0];// 取整数部分
            let float = num.split(".")[1] || "";// 取小数部分

            int = int.toString().replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, "$1,");// 整数格式化千分位
            float = this.isEmptyStr(float) ? "" : "." + float;

            num = int + float;
            return num;
        },

        // 生成随机数并转为二进制 截取前4位
        generateRandom: function () {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        },

        // 生成uuid
        generateGuid: function () {
            return (this.generateRandom() + this.generateRandom() + "-" + this.generateRandom() + "-" + this.generateRandom() + "-" + this.generateRandom() + "-" + this.generateRandom() + this.generateRandom() + this.generateRandom());
        },

        // 判断数字奇偶
        isEvenOrOdd: function (num) {
            let boolean = "";

            if (this.isNumber(num)) return boolean;

            boolean = num % 2 === 0 ? "even" : "odd";

            return boolean;
        },

        // 数字转大写汉字
        numTransferToChineseChar: function (num) {
            if (!num || this.isEmptyStr(num)) return;

            // 是否负数
            let isNegative = false;
            if (num < 0) {
                num = -num;
                isNegative = true;
            }
            if (this.isNumber(num)) num = num.toString();

            for (let i = num.length - 1; i >= 0; i--) {
                num = num.replace(",", "");// 替换money中的“,”
                num = num.replace(" ", "");// 替换money中的空格
            }
            num = num.replace("￥", "");// 替换掉可能出现的￥字符
            // 验证输入的字符是否为数字
            if (this.isNumber(num)) return;

            // ---字符处理完毕，开始转换，转换采用前后两部分分别转换---//
            let part = num.toString().split(".");
            let newChar = "";
            // 小数点前进行转化
            for (let i = part[0].length - 1; i >= 0; i--) {
                if (part[0].length > 10) return "";
                // 若数量超过拾亿单位，提示
                let tmpNewChar = "";
                let perChar = part[0].charAt(i);
                switch (perChar) {
                    case "0":
                        tmpNewChar = "零" + tmpNewChar;
                        break;
                    case "1":
                        tmpNewChar = "壹" + tmpNewChar;
                        break;
                    case "2":
                        tmpNewChar = "贰" + tmpNewChar;
                        break;
                    case "3":
                        tmpNewChar = "叁" + tmpNewChar;
                        break;
                    case "4":
                        tmpNewChar = "肆" + tmpNewChar;
                        break;
                    case "5":
                        tmpNewChar = "伍" + tmpNewChar;
                        break;
                    case "6":
                        tmpNewChar = "陆" + tmpNewChar;
                        break;
                    case "7":
                        tmpNewChar = "柒" + tmpNewChar;
                        break;
                    case "8":
                        tmpNewChar = "捌" + tmpNewChar;
                        break;
                    case "9":
                        tmpNewChar = "玖" + tmpNewChar;
                        break;
                }
                switch (part[0].length - i - 1) {
                    case 0:
                        tmpNewChar = tmpNewChar + "元";
                        break;
                    case 1:
                        if (!Object.is(0, perChar))
                            tmpNewChar = tmpNewChar + "拾";
                        break;
                    case 2:
                        if (!Object.is(0, perChar))
                            tmpNewChar = tmpNewChar + "佰";
                        break;
                    case 3:
                        if (!Object.is(0, perChar))
                            tmpNewChar = tmpNewChar + "仟";
                        break;
                    case 4:
                        tmpNewChar = tmpNewChar + "万";
                        break;
                    case 5:
                        if (!Object.is(0, perChar))
                            tmpNewChar = tmpNewChar + "拾";
                        break;
                    case 6:
                        if (!Object.is(0, perChar))
                            tmpNewChar = tmpNewChar + "佰";
                        break;
                    case 7:
                        if (!Object.is(0, perChar))
                            tmpNewChar = tmpNewChar + "仟";
                        break;
                    case 8:
                        tmpNewChar = tmpNewChar + "亿";
                        break;
                    case 9:
                        tmpNewChar = tmpNewChar + "拾";
                        break;
                }
                newChar = tmpNewChar + newChar;
            }
            // 小数点之后进行转化
            if (num.includes(".")) {
                // 小数点之后只能保留两位,系统将自动截段
                if (part[1].length > 2) part[1] = part[1].substr(0, 2);

                for (let i = 0; i < part[1].length; i++) {
                    let tmpNewChar = "";
                    let perChar = part[1].charAt(i);
                    switch (perChar) {
                        case "0":
                            tmpNewChar = "零" + tmpNewChar;
                            break;
                        case "1":
                            tmpNewChar = "壹" + tmpNewChar;
                            break;
                        case "2":
                            tmpNewChar = "贰" + tmpNewChar;
                            break;
                        case "3":
                            tmpNewChar = "叁" + tmpNewChar;
                            break;
                        case "4":
                            tmpNewChar = "肆" + tmpNewChar;
                            break;
                        case "5":
                            tmpNewChar = "伍" + tmpNewChar;
                            break;
                        case "6":
                            tmpNewChar = "陆" + tmpNewChar;
                            break;
                        case "7":
                            tmpNewChar = "柒" + tmpNewChar;
                            break;
                        case "8":
                            tmpNewChar = "捌" + tmpNewChar;
                            break;
                        case "9":
                            tmpNewChar = "玖" + tmpNewChar;
                            break;
                    }
                    if (Object.is(0, i))
                        tmpNewChar = tmpNewChar + "角";
                    if (Object.is(1, i))
                        tmpNewChar = tmpNewChar + "分";
                    newChar = newChar + tmpNewChar;
                }
            }
            // 替换所有无用汉字
            while (newChar.search("零零") != -1)
                newChar = newChar.replace("零零", "零");
            newChar = newChar.replace("零亿", "亿");
            newChar = newChar.replace("亿万", "亿");
            newChar = newChar.replace("零万", "万");
            newChar = newChar.replace("零元", "元");
            newChar = newChar.replace("零角", "");
            newChar = newChar.replace("零分", "");

            if (newChar.charAt(newChar.length - 1) == "元" || newChar.charAt(newChar.length - 1) == "角") {
                newChar = newChar + "整";
            }

            if (isNegative) {
                newChar = "负" + newChar;
            }

            return newChar;
        },

        // 加法
        addition: function (a, b) {
            let c, d, e;
            try {
                a == null ? c = "0" : c = a.toString().split(".")[1].length;
            } catch (f) {
                c = 0;
            }
            try {
                b == null ? d = "0" : d = b.toString().split(".")[1].length;
            } catch (f) {
                d = 0;
            }
            return e = Math.pow(10, Math.max(c, d)), (this.multiplication(a, e) + this.multiplication(b, e)) / e;
        },

        // 减法
        subtraction: function (a, b) {
            let c, d, e;
            try {
                a == null ? c = "0" : c = a.toString().split(".")[1].length;
            } catch (f) {
                c = 0;
            }
            try {
                b == null ? d = "0" : d = b.toString().split(".")[1].length;
            } catch (f) {
                d = 0;
            }
            return e = Math.pow(10, Math.max(c, d)), (this.multiplication(a, e) - this.multiplication(b, e)) / e;
        },

        // 乘法
        multiplication: function (a, b) {
            let c = 0, d = a == null ? "0" : a.toString(), e = b == null ? "0" : b.toString();

            try {
                c += d.split(".")[1].length;
            } catch (f) {
            }
            try {
                c += e.split(".")[1].length;
            } catch (f) {
            }

            return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
        },

        // 除法
        division: function (a, b) {
            let c, d, e = 0, f = 0;

            try {
                a == null ? e = "0" : e = a.toString().split(".")[1].length;
            } catch (g) {
            }
            try {
                b == null ? f = "0" : f = b.toString().split(".")[1].length;
            } catch (g) {
            }

            return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), this.multiplication(c / d, Math.pow(10, f - e));
        },

        /*数字操作------------------------------------------------------------------------------end*/

        /*时间Date------------------------------------------------------------------------------start*/
        dateFormatToString: function (date, fmt) { // dateFormatToString(date,"yyyy-MM-dd hh:mm:ss.S")
            let o = {
                "M+": date.getMonth() + 1,                 // 月份
                "d+": date.getDate(),                      // 日
                "h+": date.getHours(),                     // 小时
                "m+": date.getMinutes(),                   // 分
                "s+": date.getSeconds(),                   // 秒
                // "q+": Math.floor((data.getMonth() + 3) / 3), // 季度
                "q+": Math.floor(this.division(this.addition(date.getMonth(), 3), 3)), // 季度
                "S": date.getMilliseconds()                // 毫秒
            };
            if (/(y+)/.test(fmt))
                fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
            for (let k in o)
                if (new RegExp("(" + k + ")").test(fmt))
                    fmt = fmt.replace(RegExp.$1, (Object.is(RegExp.$1.length, 1)) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            return fmt;
        },

        /*时间Date------------------------------------------------------------------------------end*/

        /*对象操作------------------------------------------------------------------------------start*/

        // 判断对象是否为空
        isEmptyObject: function (object) {
            if (object && !Object.is(Object.keys(object).length, 0)) return false;

            return true;
        },

        // 清空对象属性值
        objectClear: function (object) {
            Object.keys(object).forEach(key => (object[key] = ""));
        },

        // 对象属性去除空串
        objectTrim: function (object) {
            Object.keys(object).forEach(key => {
                let value = object[key];
                if (!value) return;

                if (this.isObject(value)) {
                    this.objectTrim(value);
                } else if (!this.isString(value)) {
                    return;
                } else {
                    return object[key] = value.trim();
                }
            });
        },

        // 判断两个对象属性、属性值完全相等
        objectEquals: function (object1, object2) {
            if (!this.isObject(object1) || !this.isObject(object2)) return false;

            // 判断两个对象的属性长度
            if (!Object.is(Object.keys(object1).length, Object.keys(object2).length)) return false;

            // 根据属性键值取属性值
            for (let keys in object1) {
                // 判断object1的键值，在object2中是否存在，不存在，返回false
                if (!object2.hasOwnProperty(keys)) return false;

                if (this.isObject(object1[keys]) && this.isObject(object2[keys])) {// 如果都为对象  继续递归判断
                    if (!this.objectEquals(object1[keys], object2[keys])) return false;
                } else if (!Object.is(object1[keys], object2[keys])) {
                    return false;
                }
            }
            return true;
        },
        /*对象操作------------------------------------------------------------------------------end*/

        /*浏览器操作------------------------------------------------------------------------------start*/

        // 获取url中的参数
        getUrlParameter: function (key) {
            let reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
            let r = window.location.search.substr(1).match(reg);
            if (r != null) return unescape(r[2]);
            return null;
        },

        // 获取url
        getUrlAll: function () {
            return window.location.href;
        },

        // 获取url路径
        getUrlPath: function () {
            return window.location.pathname;
        },
        /*浏览器操作-end*/

        /*数组操作-start*/
        // 单一数组去重  ["1","2","2","3"]
        noRepeatSingle: function (array) {
            if (!this.isArray(array)) return [];

            return Array.from(new Set(array))
        },

        // 数组按某一属性分组
        groupBy: function (array, key) {// key:数组对象中的属性 此方法返回值是一个对象
            if (!this.isArray(array)) return [];

            let group = array.reduce((acc, cur) => {
                (acc[cur[key]] = acc[cur[key]] || []).push(cur);
                return acc;
            }, {});
            // 整理成数组
            // let arr = [];
            // Object.keys(group).forEach(key => {
            //     arr.push({
            //         key: key,
            //         list: group[key]
            //     });
            // });

            return group;
        },

        // 数组 按照某一属性求和
        sumByKey: function (array, key) {
            if (!this.isArray(array)) return [];

            return array.reduce((acc, cur, idx, src) => {// acc:上一次调用回调时返回的累积值  cur:正在处理的元素  idx:正在处理的当前元素的索引  src:源数组(原数组)
                return this.addition(acc, cur[key]);
            }, 0);
        },

        // 多维数组转一维数组
        transferOneArray: function (array) {// let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
            if (!Array.isArray(array)) return [];

            return array.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? this.transferOneArray(cur) : cur), [])
        },

        // 记录数组中元素重复次数
        countEleRepeatTime: function (array) {// let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
            return array.reduce((acc, cur) => {
                if (cur in acc) {
                    acc[cur]++;
                } else {
                    acc[cur] = 1;
                }
                return acc;
            }, {});
        },

        // 按照汉字和首字母分组
        groupByCharacters: function (arr) { // 数据格式  let items = [{id: "1",name: "安吉",}, {id: "2",name: "安庆",}, {id: "3",name: "大连",}, {id: "4",name: "上海",}, {id: "5",name: "北京",}];
            if (!String.prototype.localeCompare) return null;

            let letters = "*abcdefghjklmnopqrstwxyz".split("");
            let zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split("");

            let segs = [];
            let curr;
            letters.forEach((item, i) => {
                curr = {letter: item, data: []};
                arr.forEach((itm) => {
                    if ((!zh[i - 1] || zh[i - 1].localeCompare(itm.name) <= 0) && itm.name.localeCompare(zh[i]) == -1) {
                        curr.data.push(itm);
                    }
                });
                if (curr.data.length) {
                    segs.push(curr);
                    curr.data.sort(function (a, b) {
                        return a.name.localeCompare(b.name);
                    });
                }
            });
            return segs;
        },

        // 按照汉字顺序排序
        orderByCharacters: function (array) {
            let resultArray = array.sort(function (a, b) {
                    return a.name.localeCompare(b.name, "zh");
                }
            );

            return resultArray;
        },
        /*数组操作------------------------------------------------------------------------------end*/
    };

    // ork_0wKjLVL1avYpax-oDy1QPV9I openId

    $.commonMethod = new CommonMethod();
}));

